package io.renren.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class MQConfig {

	public static final String OPERATEAFTERPATQUEUE = "zh.operateAfterPayQueue";
	//	public static final String MANAGEMENTQUEUE = "MANAGEMENTQUEUE";
	public static final String USERUPGRADEQUEUE = "zh.userUpGradeQueue";
	//	public static final String LEADREWARDQUEUE = "LEADREWARDQUEUE";
//	public static final String RANGEQUEUE = "RANGEQUEUE";
	public static final String ORDER_DELAY_EXCHANGE = "zh.order.delay.exchange";
	public static final String ORDER_DELAY_ROUTING_KEY = "zh.order.delay.routing.key";
	public static final String ORDER_DELAY_QUEUE = "zh.order.delay.queue";

	public static final String ORDER_QUEUE_NAME = "zh.order.queue";

	public static final String ORDER_EXCHANGE_NAME = "zh.order.exchange";
	public static final String ORDER_ROUTING_KEY = "zh.order.routing.key";

	/**
	 * Direct模式 交换机Exchange 支付后续操作队列
	 * */
	@Bean
	public Queue OPERATEAFTERPATQUEUE() {
		return new Queue(OPERATEAFTERPATQUEUE, true);
	}

//
//	/**
//	 * Direct模式 交换机Exchange 用户团队奖对列
//	 * */
//	@Bean
//	public Queue MANAGEMENTQUEUE() {
//		return new Queue(MANAGEMENTQUEUE, true);
//	}
//
	/**
	 * Direct模式 交换机Exchange 用户升级队列
	 * */
	@Bean
	public Queue USERUPGRADEQUEUE() {
		return new Queue(USERUPGRADEQUEUE, true);
	}
//
//	/**
//	 * Direct模式 交换机Exchange 领导奖
//	 * */
//	@Bean
//	public Queue LEADREWARDQUEUE() {
//		return new Queue(LEADREWARDQUEUE, true);
//	}
//	/**
//	 * Direct模式 交换机Exchange 推荐奖励级差奖励
//	 * */
//	@Bean
//	public Queue RANGEQUEUE() {
//		return new Queue(RANGEQUEUE, true);
//	}

	/**
	 * 延迟队列配置
	 * <p>
	 * 1、params.put("x-message-ttl", 5 * 1000);
	 * 第一种方式是直接设置 Queue 延迟时间 但如果直接给队列设置过期时间,这种做法不是很灵活,（当然二者是兼容的,默认是时间小的优先）
	 * 2、rabbitTemplate.convertAndSend(book, message -> {
	 * message.getMessageProperties().setExpiration(2 * 1000 + "");
	 * return message;
	 * });
	 * 第二种就是每次发送消息动态设置延迟时间,这样我们可以灵活控制
	 **/
	@Bean
	public Queue delayOrderQueue() {
		Map<String, Object> params = new HashMap<>();
		// x-dead-letter-exchange 声明了队列里的死信转发到的DLX名称，
		params.put("x-dead-letter-exchange", ORDER_EXCHANGE_NAME);
		// x-dead-letter-routing-key 声明了这些死信在转发时携带的 routing-key 名称。
		params.put("x-dead-letter-routing-key", ORDER_ROUTING_KEY);
		/**
		 * queue: 第一个参数  队列名
		 * durable 第二个参数  是否持久化
		 * exclusive  第三个参数  是否排外 设置了排外为true的队列只可以在本次的连接中被访问，
		 * 也就是说在当前连接创建多少个channel访问都没有关系，但是如果是一个新的连接来访问不可以，
		 * autoDelete：第四个参数 是否自动删除。也就是说queue会清理自己。但是是在最后一个connection断开的时候
		 */
		return new Queue(ORDER_DELAY_QUEUE, false, false, false, params);
	}
	/**
	 * 需要将一个队列绑定到交换机上，要求该消息与一个特定的路由键完全匹配。
	 * 这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “dog”，则只有被标记为“dog”的消息才被转发，
	 * 不会转发dog.puppy，也不会转发dog.guard，只会转发dog。
	 * @return DirectExchange
	 */
	@Bean
	public DirectExchange orderDelayExchange() {
		return new DirectExchange(ORDER_DELAY_EXCHANGE);
	}
	@Bean
	public Binding dlxBinding() {
		return BindingBuilder.bind(delayOrderQueue())
				.to(orderDelayExchange())
				.with(ORDER_DELAY_ROUTING_KEY);
	}

	@Bean
	public Queue orderQueue() {
		return new Queue(ORDER_QUEUE_NAME, true);
	}
	/**
	 * 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。
	 * 符号“#”匹配一个或多个词，符号“*”匹配不多不少一个词。因此“audit.#”能够匹配到“audit.irs.corporate”，但是“audit.*” 只会匹配到“audit.irs”。
	 **/
	@Bean
	public TopicExchange orderTopicExchange() {
		return new TopicExchange(ORDER_EXCHANGE_NAME);
	}

	@Bean
	public Binding orderBinding() {
		//  如果要让延迟队列之间有关联,这里的 routingKey 和 绑定的交换机很关键
		return BindingBuilder.bind(orderQueue()).to(orderTopicExchange()).with(ORDER_ROUTING_KEY);
	}
}
